﻿#!/usr/bin/env python
# -*- coding: UTF-8 -*-

import os
import re
import shutil
import tempfile
from orioluspith.archivers.factory import PacketExtractorFactory
from orioluspith.packets.metareader import FileMetaReader
from orioluspith.packets.scriptreader import ScriptReader

class Status:
    NEW = "new"
    BAD = "bad"
    INSTALLING = "installing"
    INSTALLED = "installed"
    REMOVED = "removed"

class FullNameParseError(Exception):
    def __init__(self, message):
        Exception.__init__(self, message)

class FullName:
    def __init__(self, name, version):
        self.__name = name
        self.__version = version

    def parse(cls, full_name_string):
        pattern = re.compile("^(.+)-(\d+\.\d+\.\d+\.\d+)$")
        result = pattern.search(full_name_string)

        if not result:
            raise FullNameParseError("'%s' in not a packet full name" % full_name_string)
        
        return FullName(result.group(1), result.group(2)) 

    parse = classmethod(parse)

    @property
    def name(self):
        return self.__name 

    @property
    def version(self):
        return self.__version

    def __str__(self):
        return "%s-%s" % (self.__name, self.__version)

    def __eq__(self, other):
        if not (type(other) is type(self)):
            return False

        if self.__name != other.__name:
            return False

        if self.__version != other.__version:
            return False

        return True
    
    def __ne__(self, other):
        return not self.__eq__(other)

    def __hash__(self):
        return hash(str(self))    

class Packet:
    def __init__(self, meta, scripts=None, status=Status.NEW):
        if scripts is None:
            scripts = {}
        self.__meta = meta
        self.__status = status
        self.__scripts = scripts

    @property
    def name(self):
        return str(FullName(self.__meta.name, self.__meta.version))

    @property
    def meta(self):
        return self.__meta

    def get_status(self):
        return self.__status

    def set_status(self, status):
        self.__status = status

    status = property(get_status, set_status)

    @property
    def scripts(self):
        return self.__scripts

class FilePacket(Packet):
    def __init__(self, packet_path, status=Status.NEW, packet_extractor_factory=PacketExtractorFactory(),
        meta_reader=FileMetaReader(), script_reader=ScriptReader()):
        self.__temp_dir = tempfile.mkdtemp()
        packet_extractor = packet_extractor_factory.get_extractor(packet_path)

        packet_extractor.extract(packet_path, self.__temp_dir)
        meta = meta_reader.read(os.path.join(self.__temp_dir , "META"))
        scripts = script_reader.read(os.path.join(self.__temp_dir , "scripts"))
        Packet.__init__(self, meta, scripts, status)

    def __del__(self):
        if os.path.exists(self.__temp_dir):
            shutil.rmtree(self.__temp_dir)